package com.chhuang.huaao.filter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.filterchain.IoFilterAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.write.DefaultWriteRequest;
import org.apache.mina.core.write.WriteRequest;

import com.chhuang.huaao.handler.ServerHandler;
import com.chhuang.utils.Assert;

/**
 * mina过滤器，进行字符编码和过滤不可识别的通讯
 * @author CHHUANG
 *
 */
public class MyCodeFilter extends IoFilterAdapter {
	
	private static final Log log = LogFactory.getLog(MyCodeFilter.class);
	
	private String charset;
	
	public MyCodeFilter(String charset){
		this.charset = charset;
	}
	
	@Override
	public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
		if(message instanceof IoBuffer){
	        IoBuffer ioBuffer = (IoBuffer) message;
	        byte[] byteArray = new byte[ioBuffer.limit()];
	        ioBuffer.get(byteArray, 0, ioBuffer.limit());
	        
	        int[] intArray = new int[byteArray.length];
	        for(int i=0; i<byteArray.length; i++){
	        	if(byteArray[i]<0)
	        		intArray[i] = byteArray[i] & 0xff;
	        	else
	        		intArray[i] = byteArray[i];
	        }
	        
	        String hexStr = "";
	        for(int a : intArray){
	        	hexStr += Integer.toHexString(a)+" ";
	        }
	        
	        if("f5".equalsIgnoreCase(Integer.toHexString(intArray[0]))){//以f5开头
		        log.debug("十六进制通讯："+hexStr);
	        	nextFilter.messageReceived(session, toStatus(intArray));
	        }else {
		        String msg = new String(byteArray, this.charset);
	        	if(isCustomerCall(ServerHandler.CALLS, msg) || msg.endsWith("ModuleLogin#") || msg.endsWith("Heart#")){//是客户端发来的固定格式的字符串
		        	nextFilter.messageReceived(session, toLoginOrHeart(msg));
		        }else{
		        	log.debug("过滤掉不可识别的通讯："+msg);
		        	log.debug("过滤掉不可识别的通讯："+hexStr);
		        	session.close(true);session=null;
		        }
	        }
        }else{
        	log.debug("过滤掉不可识别的通讯");
        	session.close(true);session=null;
        }
    }

	@Override
    public void messageSent(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
    	nextFilter.messageSent(session, writeRequest);
    }
    
    @Override
    public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
    	Object message = writeRequest.getMessage();
    	if(message instanceof String){
        	byte[] responseByteArray = String.valueOf(message).getBytes(this.charset);
            IoBuffer responseIoBuffer = IoBuffer.allocate(responseByteArray.length);
            responseIoBuffer.put(responseByteArray);
            responseIoBuffer.flip();
            WriteRequest defaultWriteRequest = new DefaultWriteRequest(responseIoBuffer, writeRequest.getFuture(), writeRequest.getDestination());
        	nextFilter.filterWrite(session, defaultWriteRequest);
        }else{
        	nextFilter.filterWrite(session, writeRequest);
        }
    }
    
    /**
     * 是否为设备发来的固定格式的字符串
     * @param a
     * @param str
     * @return
     */
    private boolean isCustomerCall(String[] a, String str){
    	boolean result = false;
    	
    	if(Assert.isValidArray(a)){
	    	for(String t : a){
	    		if(str.startsWith(t)){
	    			result = true;
	    			break;
	    		}
	    	}
    	}
    	
    	return result;
    }
    
    /**
     * 转成指定格式字符串
     * @param a
     * @param str
     * @return
     */
    private String toLoginOrHeart(String msg){
    	String result = msg;
    	
    	if(msg.endsWith("ModuleLogin#")){
    		result = "LOGIN " + msg.substring(0, msg.lastIndexOf("ModuleLogin#"));
    	}else if(msg.endsWith("Heart#")){
    		result = "HEART " + msg.substring(0, msg.lastIndexOf("Heart#"));
    	}
    	
    	log.debug(result);
    	return result;
    }
    
    /**
     * 把二进制流转成字符串
     * @param byteArray
     * @return
     */
    private String toStatus(int[] intArray) {
		String result = "STATUS";
		//序列号
		String id = "";
		String str = Integer.toHexString(intArray[1]);
		if(str.length()==1) id = "0"+str; else id=str;
		str = Integer.toHexString(intArray[2]);
		if(str.length()==1) id += "0"+str; else id+=str;
		//序列号转十进制
		id = String.valueOf(Integer.parseInt(id,16));
		int len;
		if(id.length()<4){//补全0
			len = id.length();
			for(int i=0;i<4-len;i++){
				id = "0"+id;
			}
		}
		//开关状态
		String switch_s="", bin_s="", stove_s="", blower_s="", wind_s="", pump_s="", fire_s="";
		str = Integer.toBinaryString(intArray[4]);
		if(str.length()<8){//补全0
			len = str.length();
			for(int i=0;i<8-len;i++){
				str = "0"+str;
			}
		}
		char[] chars = str.toCharArray();
		len = chars.length;
		switch_s = String.valueOf(chars[len-1]);
		bin_s = String.valueOf(chars[len-2]);
		stove_s = String.valueOf(chars[len-3]);
		blower_s = String.valueOf(chars[len-4]);
		wind_s = String.valueOf(chars[len-5]);
		pump_s = String.valueOf(chars[len-6]);
		fire_s = String.valueOf(chars[len-7]);
		//运行状态
		String run_s = String.valueOf(intArray[5]);
		//温度状态
		Integer water_t=intArray[6], iwater_t=intArray[7], smoke_t=intArray[8];
		
		//报警状态
		String lessWater_w="", lessFuel_w="", hightTemp_w="";
		str = Integer.toBinaryString(intArray[9]);
		if(str.length()<8){
			len = str.length();
			for(int i=0;i<8-len;i++){
				str = "0"+str;
			}
		}
		chars = str.toCharArray();
		len = chars.length;
		lessWater_w = String.valueOf(chars[len-1]);
		lessFuel_w = String.valueOf(chars[len-2]);
		hightTemp_w = String.valueOf(chars[len-3]);
		
		//STATUS ID:No123456789 SWITCH_S:1 BIN_S:1 STOVE_S:0 BLOWER_S:1 WIND_S:1 PUMP_S:1 FIRE_S:0 WATER_T:20.8 SMOKE_T:10 IWATER_T:8 RUN_S:1 WFIRE_S:1 WWATER_S:1
		result+=" ID:"+id+
				" SWITCH_S:"+switch_s+
				" BIN_S:"+bin_s+
				" STOVE_S:"+stove_s+
				" BLOWER_S:"+blower_s+
				" WIND_S:"+wind_s+
				" PUMP_S:"+pump_s+
				" FIRE_S:"+fire_s+
				" WATER_T:"+water_t+
				" SMOKE_T:"+smoke_t+
				" IWATER_T:"+iwater_t+
				" RUN_S:"+run_s+
				" LESSWATER_W:"+lessWater_w+
				" LESSFUEL_W:"+lessFuel_w+
				" HIGHTTEMP_W:"+hightTemp_w;
		
		log.debug(result);
		return result;
	}
    
//    public static void main(String[] args) {
//		System.out.println(String.valueOf(Integer.parseInt("000b",16)));
//	}
}
